﻿using System;
using System.Collections.Generic;
using RentalSystem.Data.EF.Core;

namespace RentalSystem.Data.EF.Dao
{
    public class EFHiresDao : IHiresDao
    {
        #region Queries

        private static string GetUserCurrentHiresQuery;
        private static string ListHiresQuery;
        private static string GetByGuidQuery;

        #endregion

        private EFManager<Hires> manager;

        public EFHiresDao(RentalDatabaseEntities repository)
        {
            GetByGuidQuery = "SELECT VALUE h FROM Hires AS h WHERE h.HireGuid = @Guid;";
            GetUserCurrentHiresQuery = "SELECT VALUE h FROM Hires AS h WHERE h.UserGuid = @Guid;";
            ListHiresQuery = "SELECT VALUE h FROM Hires AS h";

            this.manager = new EFManager<Hires>(repository);
        }
        
        #region IDao1Key

        public Hires Add(Hires entity)
        {
            manager.Database.AddToHires(entity);
            manager.Save();
            return entity;
        }

        public Hires Get(string id)
        {
            QueryParam[] parameters = new QueryParam[]
                {
                    new QueryParam("@Guid", id)
                };

            var hires = manager.SQLQueryToEntity(GetByGuidQuery, parameters);

            foreach (Hires hire in hires)
            {
                return hire;
            }

            return null;
        }

        public void Delete(string guid)
        {
            manager.Database.Hires.DeleteObject(Get(guid));
            manager.Save();
        }

        public void Delete(Hires entity)
        {
            Delete(entity.HireGuid);
        }

        public void Update(Hires entity, uint fields)
        {
            if (entity == null)
                return;

            Hires fromDb = Get(entity.HireGuid);

            if (fromDb == null)
                throw new ArgumentException("Podane wypożyczenie nie występuje w bazie");

            if ((fields & (uint)HireFields.User) == (uint)HireFields.User)
                fromDb.UserGuid = entity.UserGuid;
            if ((fields & (uint)HireFields.Disc) == (uint)HireFields.Disc)
                fromDb.DiscGuid = entity.DiscGuid;
            if ((fields & (uint)HireFields.SignupDate) == (uint)HireFields.SignupDate)
                fromDb.HireSignupDate = entity.HireSignupDate;
            if ((fields & (uint)HireFields.GettingDate) == (uint)HireFields.GettingDate)
                fromDb.HireGettingDate = entity.HireGettingDate;
            if ((fields & (uint)HireFields.PlanningReturningDate) == (uint)HireFields.PlanningReturningDate)
                fromDb.HirePlanningReturningDate = entity.HirePlanningReturningDate;
            if ((fields & (uint)HireFields.ReturningDate) == (uint)HireFields.ReturningDate)
                fromDb.HireReturningDate = entity.HireReturningDate;
            if ((fields & (uint)HireFields.PlanningCost) == (uint)HireFields.PlanningCost)
                fromDb.HirePlanningCost = entity.HirePlanningCost;
            if ((fields & (uint)HireFields.IsPaidPlanningCost) == (uint)HireFields.IsPaidPlanningCost)
                fromDb.HireIsPaidPlanningCost = entity.HireIsPaidPlanningCost;
            if ((fields & (uint)HireFields.LateReward) == (uint)HireFields.LateReward)
                fromDb.HireLateReward = entity.HireLateReward;
            if ((fields & (uint)HireFields.IsPaidLateReward) == (uint)HireFields.IsPaidLateReward)
                fromDb.HireIsPaidLateReward = entity.HireIsPaidLateReward;
            if ((fields & (uint)HireFields.IsDiscReturned) == (uint)HireFields.IsDiscReturned)
                fromDb.HireIsDiscReturned = entity.HireIsDiscReturned;
            
            manager.Save();
        }

        public List<Hires> List()
        {
            List<Hires> list = new List<Hires>();
            var hires = manager.SQLQueryToEntity(ListHiresQuery);

            foreach (Hires hire in hires)
            {
                list.Add(hire);
            }

            return list;
        }

        #endregion

        public List<Hires> GetCustomerCurrentHire(string userGuid)
        {
            QueryParam[] parameters = new QueryParam[]
                {
                    new QueryParam("@Guid", userGuid)
                };

            var hires = manager.SQLQueryToEntity(ListHiresQuery, parameters);

            List<Hires> result = new List<Hires>();

            foreach (Hires hire in hires)
            {
                if(!hire.HireIsDiscReturned)
                    result.Add(hire);
            }

            return result;
        }
        
        public List<Hires> ListCurrentHires()
        {
            var hires = manager.SQLQueryToEntity(ListHiresQuery);

            List<Hires> result = new List<Hires>();

            foreach (Hires hire in hires)
            {
                if (!hire.HireIsDiscReturned)
                    result.Add(hire);
            }

            return result;
        }
    }
}
